/* $Id: DataObjectType.java,v 1.2 2003/08/02 19:20:02 survey Exp $
 * 
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.medbeans.modules.search.types;


import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
//import java.io.IOException;

import org.openide.cookies.InstanceCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.Repository;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.Node;
import org.openide.util.WeakListener;
//import org.openidex.search.DataObjectSearchGroup;
//import org.openidex.search.SearchGroup;
import org.openidex.search.SearchType;


/**
 * Type used by SearchType which can be part of <code>DataObjectSearchGroup</code>.
 *
 * @author  Petr Kuzel
 * @see org.openidex.search.DataObjectSearchGroup
 */
public abstract class DataObjectType extends SearchType {

    /** Serial version UID. */
    static final long serialVersionUID = 1L; // forever 1

    /** Property change listener. */
    private PropertyChangeListener propListener;
    
    
    /** Prepares search object for search. Listens on the underlying 
     * object and fires SearchType.PROP_OBJECT_CHANGED property change
     * in cases object has changed. */
    protected void prepareSearchObject(Object searchObject) {
        DataObject dataObject = extractDataObject(searchObject);

        if(dataObject == null) 
            return;
        
        dataObject.addPropertyChangeListener(
            WeakListener.propertyChange(getDataObjectListener(), dataObject)
        );
        
    }

    /** Gets property change listener which listens on changes on searched data object. */
    private synchronized PropertyChangeListener getDataObjectListener() {
        if(propListener == null) {
            propListener = new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent evt) {
                    if(DataObject.PROP_COOKIE.equals(evt.getPropertyName()))
                        firePropertyChange(PROP_OBJECT_CHANGED, null, evt.getSource());
                }
            };
        }
        
        return propListener;
    }
    
    /** Tests object. Implements superclass abstract method. */
    public boolean testObject(Object object) {
        DataObject dataObject = extractDataObject(object);
            
        if(dataObject == null)
            return false;
        
        return testDataObject(dataObject);
    }

    /** Gets data object from search object. */
    private static DataObject extractDataObject(Object object) {
        DataObject dataObject = null;
        
        if(object instanceof DataObject) {
            dataObject = (DataObject)object;
        } else if(object instanceof FileObject) {
            try{
                dataObject = DataObject.find((FileObject)object);
            } catch(DataObjectNotFoundException dnfe) {
                dnfe.printStackTrace();
            }
        }

        return dataObject;
    }

    /** Creates search types classes. */
    protected Class[] createSearchTypeClasses() {
        return new Class[] {DataObject.class};
    }
    
    /** Process data object. */
    protected abstract boolean testDataObject(DataObject dataObject);

    /** Tests if it is enabled on specified root nodes. 
     * @return true if any node represent repository node */
    public boolean enabled(Node[] nodes) {
        
        if(nodes == null || nodes.length == 0) {
            return false;
        }

        // NodeCookie test
        for(int i =0; i < nodes.length; i++ ) {

            Node obj = nodes[i];

            //     if (obj.isLeaf()) continue; // optimalization that can cause probs in object browser

            if(obj.getCookie(DataFolder.class) != null) {
                return true;
            }

            InstanceCookie.Of ic = (InstanceCookie.Of)obj.getCookie(InstanceCookie.Of.class);
            if(ic != null && ic.instanceOf(Repository.class)) {
                return true;
            }
        }

        return false;
    }

}
